﻿//======================================================================
//
//	Cross-Platform XNA Menu System
//  http://cpxms.codeplex.com/
//
//  All code and content licensed under Microsoft Public License (Ms-PL)	
//
//======================================================================
//
//	File:		ImportedContentItem.cs
//
//	Author:		MJP
//
//	Date:		08/05/09
//
//======================================================================

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Xml.Serialization;
using System.Drawing.Design;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;


namespace CPXMenu
{
    public class ImportedContentDirectory : ImportedContentNode
    {
        List<ImportedContentDirectory> directories = new List<ImportedContentDirectory>();
        List<ImportedContentItem> content = new List<ImportedContentItem>();
        string name = string.Empty;
        string path = string.Empty;
        ImportedContentDirectory parentDirectory = null;

        [Category("Imported Content Directory Properties")]
        [Description("The name of the directory")]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        [Category("Imported Content Directory Properties")]
        [Description("The path of the directory")]
        public string Path
        {
            get { return path; }
            set { path = value; }
        }

        [Browsable(false)]
        public List<ImportedContentItem> Content
        {
            get { return content; }
            set { content = value; }
        }

        [Browsable(false)]
        public List<ImportedContentDirectory> Directories
        {
            get { return directories; }
            set { directories = value; }
        }

        [Browsable(false)]
        [XmlIgnore]
        public ImportedContentDirectory ParentDirectory
        {
            get { return parentDirectory; }
        }

        public ImportedContentDirectory()
        {

        }

        public ImportedContentDirectory(string name, string path)
        {
            this.name = name;
            this.path = path;
        }

        internal void SetParentDirectory(ImportedContentDirectory parentDirectory)
        {
            this.parentDirectory = parentDirectory;
            foreach (ImportedContentItem item in content)
                item.SetParentDirectory(this);
            foreach (ImportedContentDirectory directory in directories)
                directory.SetParentDirectory(this);
        }
    }

    /// <summary>
    /// Stores information about a content item that was imported through an editor
    /// </summary>
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class ImportedContentItem : ImportedContentNode
    {
        List<ulong> ownerIDs = new List<ulong>();
        string inputPath = string.Empty;
        string name = string.Empty;
        string path = string.Empty;
        string importerAssembly = string.Empty;
        string importer = string.Empty;
        string processorAssembly = string.Empty;
        string processor = string.Empty;
        string typeName = string.Empty;
        string typeAssembly = string.Empty;
        Type cachedType = null;
        List<ContentBuildParameter> buildParameters = new List<ContentBuildParameter>();
        ImportedContentDirectory parentDirectory = null;

        [ReadOnly(true)]
        [DisplayName("Owner IDs")]
        [Category("Imported Content Properties")]
        public List<ulong> OwnerIDs
        {
            get { return ownerIDs; }
            set { ownerIDs = value; }
        }

        [ReadOnly(true)]
        [DisplayName("Source File")]
        [Category("Imported Content Properties")]
        public string InputPath
        {
            get { return inputPath; }
            set { inputPath = value; }
        }

        [ReadOnly(true)]
        [DisplayName("Asset Name")]
        [Category("Imported Content Properties")]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        [ReadOnly(true)]
        [DisplayName("Asset Path")]
        [Category("Imported Content Properties")]
        public string Path
        {
            get { return path; }
            set { path = value; }
        }

        [ReadOnly(true)]
        [DisplayName("Content Importer Assembly")]
        [Category("Imported Content Properties")]
        public string ImporterAssembly
        {
            get { return importerAssembly; }
            set { importerAssembly = value; }
        }

        [ReadOnly(true)]
        [DisplayName("Content Importer")]
        [Category("Imported Content Properties")]
        public string Importer
        {
            get { return importer; }
            set { importer = value; }
        }

        [ReadOnly(true)]
        [DisplayName("Content Processor Assembly")]
        [Category("Imported Content Properties")]
        public string ProcessorAssembly
        {
            get { return processorAssembly; }
            set { processorAssembly = value; }
        }

        [ReadOnly(true)]
        [DisplayName("Content Processor")]
        [Category("Imported Content Properties")]
        public string Processor
        {
            get { return processor; }
            set { processor = value; }
        }

        [ReadOnly(true)]
        [DisplayName("Type Name")]
        [Category("Imported Content Properties")]
        public string TypeName
        {
            get { return typeName; }
            set 
            {
                string prevValue = typeName;

                typeName = value;

                if (prevValue != typeName)
                    GenerateCachedType();
            }
        }

        [ReadOnly(true)]
        [DisplayName("Type Assembly")]
        [Category("Imported Content Properties")]
        public string TypeAssembly
        {
            get { return typeAssembly; }
            set 
            {
                string prevValue = typeAssembly;

                typeAssembly = value;

                if (prevValue != typeAssembly)
                    GenerateCachedType();
            }
        }

        [Browsable(false)]
        [XmlIgnore]
        public Type Type
        {
            get { return cachedType; }
        }

        [Browsable(false)]
        public List<ContentBuildParameter> BuildParameters
        {
            get { return buildParameters; }
            set { buildParameters = value; }
        }

        [Browsable(false)]
        public ImportedContentDirectory ParentDirectory
        {
            get { return parentDirectory; }
        }

        public ImportedContentItem()
        {
            
        }

        internal void SetParentDirectory(ImportedContentDirectory parentDirectory)
        {
            this.parentDirectory = parentDirectory;
        }

        private void GenerateCachedType()
        {
            if (string.IsNullOrEmpty(typeName) || string.IsNullOrEmpty(typeAssembly))
                cachedType = null;

            Assembly assembly = Assembly.Load(new AssemblyName(typeAssembly));
            cachedType = assembly.GetType(typeName);
        }
    }

    public class ImportedContentNode
    {

    }

    public struct ContentBuildParameter
    {
        public string Name;
        public object Value;

        public ContentBuildParameter(string name, object value)
        {
            Name = name;
            Value = value;
        }
    }
}